package com.demo.spring.bean注解;

import java.util.Set;

import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.type.MethodMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;

public class 自定义实现Bean注解 {
	
	public static void main(String[] args) throws Exception {
		GenericApplicationContext context = new GenericApplicationContext();
		context.registerBeanDefinition("config", new AnnotatedGenericBeanDefinition(Config.class));
		
		// 手动实现@Bean
		CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
		MetadataReader reader = factory.getMetadataReader(new ClassPathResource("com/demo/spring/bean注解/Config.class"));
		Set<MethodMetadata> methods = reader.getAnnotationMetadata().getAnnotatedMethods(Bean.class.getName());
		for(MethodMetadata method : methods) {
			System.out.println(method);
			Object initMethodo = method.getAnnotationAttributes(Bean.class.getName()).get("initMethod");
			BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
			builder.setFactoryMethodOnBean(method.getMethodName(), "config");
			// 像bean3这种还需要指定装配模式，用构造方法模式
			builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
			if(initMethodo != null && initMethodo.toString().length() > 0) {
				builder.setInitMethodName(initMethodo.toString());
			}
			AbstractBeanDefinition bd = builder.getBeanDefinition();
			context.getDefaultListableBeanFactory().registerBeanDefinition(method.getMethodName(), bd);
		}
		
		context.refresh();
		for(String name : context.getBeanDefinitionNames()) {
			System.out.println(name);
		}
	}

}
